import { PartialType } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
import {
    IsBoolean,
    IsDateString,
    IsDefined,
    IsEnum,
    IsNotEmpty,
    IsNumber,
    IsOptional,
    IsUUID,
    Max,
    MaxLength,
    Min,
    ValidateIf,
} from 'class-validator';
import { isNil, toNumber } from 'lodash';

import { toBoolean } from '@/modules/core/helpers';
import { PaginateOptions } from '@/modules/database/types';

import { PostOrderType } from '../constants';
/**
 * 文章分页查询验证
 */
export class QueryPostDto implements PaginateOptions {
    @Transform(({ value }) => toBoolean(value))
    @IsBoolean()
    @IsOptional()
    isPublished?: boolean;

    @IsEnum(PostOrderType, {
        message: `排序规则必须是${Object.values(PostOrderType).join(',')}中的一项`,
    })
    @IsOptional()
    orderBy?: PostOrderType;

    @Transform(({ value }) => toNumber(value))
    @Min(1, { message: '当前页数必须大于1' })
    @IsNumber()
    @IsOptional()
    page = 1;

    @Transform(({ value }) => toNumber(value))
    @Min(1, { message: '每页显示数据必须大于1' })
    @IsNumber()
    @IsOptional()
    limit = 10;
}
/**
 * 文章创建验证
 */
export class CreatePostDto {
    @Max(255, { message: `文章标题长度不得超过$constraint1` })
    @IsNotEmpty({ groups: ['create'], message: '文章标题为必填' })
    @IsOptional({ groups: ['update'] })
    title: string;

    @IsNotEmpty({ groups: ['create'], message: '文章内容为必填项' })
    @IsOptional({ groups: ['update'] })
    body: string;

    @MaxLength(500, { always: true, message: '文章描述长度不得超过$constraint1' })
    @IsOptional({ always: true })
    summary?: string;

    @MaxLength(20, { each: true, always: true, message: '每项关键字的长度不得超过20' })
    @IsOptional({ always: true })
    keywords?: string[];

    @IsDateString({ strict: true }, { always: true })
    @IsOptional({ always: true })
    @ValidateIf((value) => !isNil(value.publishedAt))
    @Transform(({ value }) => (value === 'null' ? null : value))
    publishedAt?: Date;

    @IsUUID(
        undefined, // uuid版本
        { each: true, always: true, message: '分类ID格式不正确' },
    )
    @IsOptional({ always: true })
    categories?: string[];

    @Transform(({ value }) => toNumber(value))
    @Min(0, { always: true, message: '排序必须大于0' })
    @IsNumber(
        undefined, // 数字转换选项
        { always: true },
    )
    @IsOptional({ always: true })
    customOrder = 0;
}

/**
 * 文章更新验证
 */
export class UpdatePostDto extends PartialType(CreatePostDto) {
    @IsUUID(undefined, { groups: ['update'], message: '文章ID格式错误' })
    @IsDefined({ groups: ['update'], message: '文章格式必须指定' })
    id: string;
}
